<template>
  <div class="abstract-background">
    <canvas ref="canvasRef"></canvas>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue'

const props = defineProps({
  config: {
    type: Object,
    default: () => ({
      style: 'fluid',
      colors: ['#667eea', '#764ba2', '#f093fb']
    })
  }
})

const canvasRef = ref(null)
let ctx = null
let animationId = null
let time = 0

const drawFluid = () => {
  if (!ctx || !canvasRef.value) return

  const { width, height } = canvasRef.value
  const colors = props.config.colors

  for (let x = 0; x < width; x += 10) {
    for (let y = 0; y < height; y += 10) {
      const colorIndex = Math.floor(
        (Math.sin(x * 0.01 + time) + Math.cos(y * 0.01 + time * 0.5)) * colors.length / 2
      )
      const color = colors[Math.abs(colorIndex) % colors.length]
      
      ctx.fillStyle = color + '40'
      ctx.fillRect(x, y, 10, 10)
    }
  }
}

const drawLines = () => {
  if (!ctx || !canvasRef.value) return

  const { width, height } = canvasRef.value
  const colors = props.config.colors

  ctx.clearRect(0, 0, width, height)

  for (let i = 0; i < 50; i++) {
    const startX = (Math.sin(time + i) * 0.5 + 0.5) * width
    const startY = (Math.cos(time + i * 0.5) * 0.5 + 0.5) * height
    const endX = (Math.sin(time + i + 1) * 0.5 + 0.5) * width
    const endY = (Math.cos(time + i * 0.5 + 1) * 0.5 + 0.5) * height

    const gradient = ctx.createLinearGradient(startX, startY, endX, endY)
    gradient.addColorStop(0, colors[i % colors.length] + '80')
    gradient.addColorStop(1, colors[(i + 1) % colors.length] + '80')

    ctx.strokeStyle = gradient
    ctx.lineWidth = 2
    ctx.beginPath()
    ctx.moveTo(startX, startY)
    ctx.lineTo(endX, endY)
    ctx.stroke()
  }
}

const drawLight = () => {
  if (!ctx || !canvasRef.value) return

  const { width, height } = canvasRef.value
  const colors = props.config.colors

  ctx.clearRect(0, 0, width, height)

  for (let i = 0; i < 20; i++) {
    const x = width / 2 + Math.sin(time + i) * width / 3
    const y = height / 2 + Math.cos(time + i * 0.7) * height / 3
    const radius = 50 + Math.sin(time + i) * 30

    const gradient = ctx.createRadialGradient(x, y, 0, x, y, radius)
    gradient.addColorStop(0, colors[i % colors.length] + '80')
    gradient.addColorStop(1, colors[i % colors.length] + '00')

    ctx.fillStyle = gradient
    ctx.beginPath()
    ctx.arc(x, y, radius, 0, Math.PI * 2)
    ctx.fill()
  }
}

const animate = () => {
  if (!ctx || !canvasRef.value) return

  time += 0.01

  if (props.config.style === 'fluid') {
    drawFluid()
  } else if (props.config.style === 'lines') {
    drawLines()
  } else if (props.config.style === 'light') {
    drawLight()
  }

  animationId = requestAnimationFrame(animate)
}

const init = () => {
  const canvas = canvasRef.value
  if (!canvas) return

  canvas.width = canvas.offsetWidth
  canvas.height = canvas.offsetHeight
  ctx = canvas.getContext('2d')

  // 设置初始背景
  ctx.fillStyle = '#ffffff'
  ctx.fillRect(0, 0, canvas.width, canvas.height)
}

const handleResize = () => {
  init()
}

onMounted(() => {
  init()
  animate()
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  if (animationId) {
    cancelAnimationFrame(animationId)
  }
  window.removeEventListener('resize', handleResize)
})

watch(() => props.config, () => {
  init()
  time = 0
}, { deep: true })
</script>

<style scoped>
.abstract-background {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  background: #ffffff;
}

canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: block;
}
</style>

